{
 "cells": [
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-30T06:54:08.428268Z",
     "start_time": "2024-05-30T06:54:08.300572Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "from torch.utils.data import DataLoader, TensorDataset\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "\n",
    "# 假设data是一个包含视频流量数据的NumPy数组\n",
    "scaler = MinMaxScaler(feature_range=(0, 1))\n",
    "data_scaled = scaler.fit_transform(data)\n",
    "\n",
    "# 创建时间序列数据集\n",
    "def create_dataset(data, seq_length):\n",
    "    xs, ys = [], []\n",
    "    for i in range(len(data) - seq_length):\n",
    "        xs.append(data[i:i + seq_length])\n",
    "        ys.append(data[i + seq_length])\n",
    "    return torch.tensor(xs), torch.tensor(ys)\n",
    "\n",
    "seq_length = 50  # 定义序列长度\n",
    "X, y = create_dataset(data_scaled, seq_length)\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
    "\n",
    "# 转换为PyTorch DataLoader\n",
    "train_dataset = TensorDataset(X_train, y_train)\n",
    "test_dataset = TensorDataset(X_test, y_test)\n",
    "train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)\n",
    "test_loader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)\n",
    "\n",
    "# 定义RNN模型\n",
    "class LSTMModel(nn.Module):\n",
    "    def __init__(self, input_size, hidden_layer_size, num_layers, output_size):\n",
    "        super(LSTMModel, self).__init__()\n",
    "        self.hidden_layer_size = hidden_layer_size\n",
    "        self.num_layers = num_layers\n",
    "        self.lstm = nn.LSTM(input_size, hidden_layer_size, num_layers, batch_first=True)\n",
    "        self.fc = nn.Linear(hidden_layer_size, output_size)\n",
    "\n",
    "    def forward(self, x):\n",
    "        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_layer_size)\n",
    "        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_layer_size)\n",
    "\n",
    "        out, _ = self.lstm(x, (h0, c0))\n",
    "        out = self.fc(out[:, -1, :])  # 取序列最后一个时间步的输出\n",
    "        return out\n",
    "\n",
    "input_size = 1  # 特征数量\n",
    "hidden_layer_size = 100  # 隐藏层大小\n",
    "num_layers = 2  # 层数\n",
    "output_size = 1  # 输出大小\n",
    "\n",
    "model = LSTMModel(input_size, hidden_layer_size, num_layers, output_size)\n",
    "\n",
    "# 定义损失函数和优化器\n",
    "criterion = nn.MSELoss()\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
    "\n",
    "# 训练模型\n",
    "epochs = 100\n",
    "for epoch in range(epochs):\n",
    "    for i, (inputs, targets) in enumerate(train_loader):\n",
    "        optimizer.zero_grad()\n",
    "\n",
    "        outputs = model(inputs)\n",
    "        loss = criterion(outputs, targets)\n",
    "\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "    print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')\n",
    "\n",
    "# 模型评估\n",
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    predictions = model(X_test)\n",
    "    test_loss = criterion(predictions, y_test)\n",
    "print(f'Test Loss: {test_loss.item():.4f}')\n"
   ],
   "id": "initial_id",
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "Expected 2D array, got 1D array instead:\narray=[ 0.          0.00628314  0.01256604 ... -0.01884844 -0.01256604\n -0.00628314].\nReshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mValueError\u001B[0m                                Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[9], line 9\u001B[0m\n\u001B[0;32m      7\u001B[0m \u001B[38;5;66;03m# 假设data是一个包含视频流量数据的NumPy数组\u001B[39;00m\n\u001B[0;32m      8\u001B[0m scaler \u001B[38;5;241m=\u001B[39m MinMaxScaler(feature_range\u001B[38;5;241m=\u001B[39m(\u001B[38;5;241m0\u001B[39m, \u001B[38;5;241m1\u001B[39m))\n\u001B[1;32m----> 9\u001B[0m data_scaled \u001B[38;5;241m=\u001B[39m \u001B[43mscaler\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mfit_transform\u001B[49m\u001B[43m(\u001B[49m\u001B[43mdata\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m     11\u001B[0m \u001B[38;5;66;03m# 创建时间序列数据集\u001B[39;00m\n\u001B[0;32m     12\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mcreate_dataset\u001B[39m(data, seq_length):\n",
      "File \u001B[1;32mC:\\Development\\SDK\\Anaconda3\\envs\\ai\\lib\\site-packages\\sklearn\\utils\\_set_output.py:157\u001B[0m, in \u001B[0;36m_wrap_method_output.<locals>.wrapped\u001B[1;34m(self, X, *args, **kwargs)\u001B[0m\n\u001B[0;32m    155\u001B[0m \u001B[38;5;129m@wraps\u001B[39m(f)\n\u001B[0;32m    156\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mwrapped\u001B[39m(\u001B[38;5;28mself\u001B[39m, X, \u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs):\n\u001B[1;32m--> 157\u001B[0m     data_to_wrap \u001B[38;5;241m=\u001B[39m \u001B[43mf\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mX\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43margs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    158\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(data_to_wrap, \u001B[38;5;28mtuple\u001B[39m):\n\u001B[0;32m    159\u001B[0m         \u001B[38;5;66;03m# only wrap the first output for cross decomposition\u001B[39;00m\n\u001B[0;32m    160\u001B[0m         return_tuple \u001B[38;5;241m=\u001B[39m (\n\u001B[0;32m    161\u001B[0m             _wrap_data_with_container(method, data_to_wrap[\u001B[38;5;241m0\u001B[39m], X, \u001B[38;5;28mself\u001B[39m),\n\u001B[0;32m    162\u001B[0m             \u001B[38;5;241m*\u001B[39mdata_to_wrap[\u001B[38;5;241m1\u001B[39m:],\n\u001B[0;32m    163\u001B[0m         )\n",
      "File \u001B[1;32mC:\\Development\\SDK\\Anaconda3\\envs\\ai\\lib\\site-packages\\sklearn\\base.py:916\u001B[0m, in \u001B[0;36mTransformerMixin.fit_transform\u001B[1;34m(self, X, y, **fit_params)\u001B[0m\n\u001B[0;32m    912\u001B[0m \u001B[38;5;66;03m# non-optimized default implementation; override when a better\u001B[39;00m\n\u001B[0;32m    913\u001B[0m \u001B[38;5;66;03m# method is possible for a given clustering algorithm\u001B[39;00m\n\u001B[0;32m    914\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m y \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m    915\u001B[0m     \u001B[38;5;66;03m# fit method of arity 1 (unsupervised transformation)\u001B[39;00m\n\u001B[1;32m--> 916\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mfit\u001B[49m\u001B[43m(\u001B[49m\u001B[43mX\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mfit_params\u001B[49m\u001B[43m)\u001B[49m\u001B[38;5;241m.\u001B[39mtransform(X)\n\u001B[0;32m    917\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m    918\u001B[0m     \u001B[38;5;66;03m# fit method of arity 2 (supervised transformation)\u001B[39;00m\n\u001B[0;32m    919\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfit(X, y, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mfit_params)\u001B[38;5;241m.\u001B[39mtransform(X)\n",
      "File \u001B[1;32mC:\\Development\\SDK\\Anaconda3\\envs\\ai\\lib\\site-packages\\sklearn\\preprocessing\\_data.py:435\u001B[0m, in \u001B[0;36mMinMaxScaler.fit\u001B[1;34m(self, X, y)\u001B[0m\n\u001B[0;32m    433\u001B[0m \u001B[38;5;66;03m# Reset internal state before fitting\u001B[39;00m\n\u001B[0;32m    434\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_reset()\n\u001B[1;32m--> 435\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mpartial_fit\u001B[49m\u001B[43m(\u001B[49m\u001B[43mX\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43my\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mC:\\Development\\SDK\\Anaconda3\\envs\\ai\\lib\\site-packages\\sklearn\\base.py:1152\u001B[0m, in \u001B[0;36m_fit_context.<locals>.decorator.<locals>.wrapper\u001B[1;34m(estimator, *args, **kwargs)\u001B[0m\n\u001B[0;32m   1145\u001B[0m     estimator\u001B[38;5;241m.\u001B[39m_validate_params()\n\u001B[0;32m   1147\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m config_context(\n\u001B[0;32m   1148\u001B[0m     skip_parameter_validation\u001B[38;5;241m=\u001B[39m(\n\u001B[0;32m   1149\u001B[0m         prefer_skip_nested_validation \u001B[38;5;129;01mor\u001B[39;00m global_skip_validation\n\u001B[0;32m   1150\u001B[0m     )\n\u001B[0;32m   1151\u001B[0m ):\n\u001B[1;32m-> 1152\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mfit_method\u001B[49m\u001B[43m(\u001B[49m\u001B[43mestimator\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43margs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mC:\\Development\\SDK\\Anaconda3\\envs\\ai\\lib\\site-packages\\sklearn\\preprocessing\\_data.py:473\u001B[0m, in \u001B[0;36mMinMaxScaler.partial_fit\u001B[1;34m(self, X, y)\u001B[0m\n\u001B[0;32m    467\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mTypeError\u001B[39;00m(\n\u001B[0;32m    468\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mMinMaxScaler does not support sparse input. \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    469\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mConsider using MaxAbsScaler instead.\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    470\u001B[0m     )\n\u001B[0;32m    472\u001B[0m first_pass \u001B[38;5;241m=\u001B[39m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28mhasattr\u001B[39m(\u001B[38;5;28mself\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mn_samples_seen_\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m--> 473\u001B[0m X \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_validate_data\u001B[49m\u001B[43m(\u001B[49m\n\u001B[0;32m    474\u001B[0m \u001B[43m    \u001B[49m\u001B[43mX\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m    475\u001B[0m \u001B[43m    \u001B[49m\u001B[43mreset\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mfirst_pass\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m    476\u001B[0m \u001B[43m    \u001B[49m\u001B[43mdtype\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mFLOAT_DTYPES\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m    477\u001B[0m \u001B[43m    \u001B[49m\u001B[43mforce_all_finite\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mallow-nan\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[0;32m    478\u001B[0m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    480\u001B[0m data_min \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39mnanmin(X, axis\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m0\u001B[39m)\n\u001B[0;32m    481\u001B[0m data_max \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39mnanmax(X, axis\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m0\u001B[39m)\n",
      "File \u001B[1;32mC:\\Development\\SDK\\Anaconda3\\envs\\ai\\lib\\site-packages\\sklearn\\base.py:605\u001B[0m, in \u001B[0;36mBaseEstimator._validate_data\u001B[1;34m(self, X, y, reset, validate_separately, cast_to_ndarray, **check_params)\u001B[0m\n\u001B[0;32m    603\u001B[0m         out \u001B[38;5;241m=\u001B[39m X, y\n\u001B[0;32m    604\u001B[0m \u001B[38;5;28;01melif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m no_val_X \u001B[38;5;129;01mand\u001B[39;00m no_val_y:\n\u001B[1;32m--> 605\u001B[0m     out \u001B[38;5;241m=\u001B[39m \u001B[43mcheck_array\u001B[49m\u001B[43m(\u001B[49m\u001B[43mX\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43minput_name\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mX\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mcheck_params\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    606\u001B[0m \u001B[38;5;28;01melif\u001B[39;00m no_val_X \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m no_val_y:\n\u001B[0;32m    607\u001B[0m     out \u001B[38;5;241m=\u001B[39m _check_y(y, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mcheck_params)\n",
      "File \u001B[1;32mC:\\Development\\SDK\\Anaconda3\\envs\\ai\\lib\\site-packages\\sklearn\\utils\\validation.py:938\u001B[0m, in \u001B[0;36mcheck_array\u001B[1;34m(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator, input_name)\u001B[0m\n\u001B[0;32m    936\u001B[0m     \u001B[38;5;66;03m# If input is 1D raise error\u001B[39;00m\n\u001B[0;32m    937\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m array\u001B[38;5;241m.\u001B[39mndim \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m1\u001B[39m:\n\u001B[1;32m--> 938\u001B[0m         \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[0;32m    939\u001B[0m             \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mExpected 2D array, got 1D array instead:\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124marray=\u001B[39m\u001B[38;5;132;01m{}\u001B[39;00m\u001B[38;5;124m.\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    940\u001B[0m             \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mReshape your data either using array.reshape(-1, 1) if \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    941\u001B[0m             \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124myour data has a single feature or array.reshape(1, -1) \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    942\u001B[0m             \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mif it contains a single sample.\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;241m.\u001B[39mformat(array)\n\u001B[0;32m    943\u001B[0m         )\n\u001B[0;32m    945\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m dtype_numeric \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;28mhasattr\u001B[39m(array\u001B[38;5;241m.\u001B[39mdtype, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mkind\u001B[39m\u001B[38;5;124m\"\u001B[39m) \u001B[38;5;129;01mand\u001B[39;00m array\u001B[38;5;241m.\u001B[39mdtype\u001B[38;5;241m.\u001B[39mkind \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mUSV\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[0;32m    946\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[0;32m    947\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdtype=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mnumeric\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m is not compatible with arrays of bytes/strings.\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    948\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mConvert your data to numeric values explicitly instead.\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    949\u001B[0m     )\n",
      "\u001B[1;31mValueError\u001B[0m: Expected 2D array, got 1D array instead:\narray=[ 0.          0.00628314  0.01256604 ... -0.01884844 -0.01256604\n -0.00628314].\nReshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample."
     ]
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "from torch.utils.data import DataLoader, TensorDataset\n",
    "\n",
    "# 生成模拟数据\n",
    "# 假设我们有一个时间序列数据，这里我们使用正弦波函数生成\n",
    "np.random.seed(0)\n",
    "torch.manual_seed(0)\n",
    "\n",
    "def generate_wave_data(amplitude, frequency, phase, duration, sample_rate):\n",
    "    t = np.arange(0, duration, 1/sample_rate)\n",
    "    data = amplitude * np.sin(2 * np.pi * frequency * t + phase)\n",
    "    return data\n",
    "\n",
    "# 参数设置\n",
    "sample_rate = 100  # 采样率\n",
    "duration = 1000    # 数据时长（单位：秒）\n",
    "seq_length = 50     # 序列长度\n",
    "\n",
    "# 生成数据\n",
    "amplitude = 1.0\n",
    "frequency = 0.1\n",
    "phase = 0\n",
    "data = generate_wave_data(amplitude, frequency, phase, duration, sample_rate)\n",
    "\n",
    "# 归一化数据\n",
    "scaler = MinMaxScaler(feature_range=(0, 1))\n",
    "data_scaled = scaler.fit_transform(data.reshape(-1, 1)).reshape(-1)\n",
    "\n",
    "# 创建时间序列数据集\n",
    "X, y = create_dataset(data_scaled, seq_length)\n",
    "\n",
    "# 转换为PyTorch张量\n",
    "X_tensor = torch.tensor(X, dtype=torch.float32)\n",
    "y_tensor = torch.tensor(y, dtype=torch.float32)\n",
    "\n",
    "# 创建数据加载器\n",
    "train_size = int(0.8 * len(X_tensor))\n",
    "test_size = len(X_tensor) - train_size\n",
    "X_train, X_test = X_tensor[:train_size], X_tensor[train_size:]\n",
    "y_train, y_test = y_tensor[:train_size], y_tensor[train_size:]\n",
    "\n",
    "train_dataset = TensorDataset(X_train, y_train)\n",
    "test_dataset = TensorDataset(X_test, y_test)\n",
    "\n",
    "batch_size = 64\n",
    "train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)\n",
    "test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)\n",
    "\n",
    "# 定义LSTM模型（这里使用之前定义的LSTMModel类）\n",
    "input_size = 1\n",
    "hidden_layer_size = 50\n",
    "num_layers = 1\n",
    "output_size = 1\n",
    "\n",
    "model = LSTMModel(input_size, hidden_layer_size, num_layers, output_size)\n",
    "\n",
    "# 定义损失函数和优化器\n",
    "criterion = nn.MSELoss()\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
    "\n",
    "# 训练模型\n",
    "epochs = 100\n",
    "for epoch in range(epochs):\n",
    "    model.train()\n",
    "    for inputs, targets in train_loader:\n",
    "        optimizer.zero_grad()\n",
    "        outputs = model(inputs)\n",
    "        loss = criterion(outputs, targets)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "    print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')\n",
    "\n",
    "# 模型评估\n",
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    predictions = model(X_test.unsqueeze(1))  # 增加维度以匹配模型的期望输入\n",
    "    test_loss = criterion(predictions, y_test.unsqueeze(1))\n",
    "print(f'Test Loss: {test_loss.item():.4f}')\n",
    "\n",
    "# 绘制预测结果\n",
    "predicted_data = scaler.inverse_transform(predictions.numpy().reshape(-1, 1)).reshape(-1)\n",
    "original_data = scaler.inverse_transform(y_test.numpy().reshape(-1, 1)).reshape(-1)\n",
    "\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.plot(original_data, label='Original Data')\n",
    "plt.plot(predicted_data, label='Predicted Data')\n",
    "plt.legend()\n",
    "plt.show()"
   ],
   "id": "2d9225c5ecbeec84",
   "outputs": [],
   "execution_count": null
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
